#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "select_serv.hpp"

using namespace std;
int main()
{
    //创建侦听套接字
    int listen_sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(listen_sock < 0)
    {
        perror("socket");
        return 0;
    }
    //连接
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(28989);
    addr.sin_addr.s_addr = inet_addr("0.0.0.0");
    int ret = bind(listen_sock,(struct sockaddr*)&addr,sizeof(addr));
    if(ret < 0)
    {
        perror("bind");
        return 0;
    }
    //监听
    ret = listen(listen_sock,1);
    if(ret < 0)
    {
        perror("listen");
        return 0;
    }
    //创建select_serv对象
    SelectServ select_svr;
    //添加侦听套接字
    select_svr.Addfd(listen_sock);
    while(1)
    {
        //接收回来vec
        vector<int> vec;
        //返回select的监控数量
        int ret = select_svr.Select(&vec);
        if(ret < 0)
        {
            perror("select");
            return 0;
        }
        else if(ret == 0)
        {
            continue;
        }
        //正常的描述符 处理
        for(size_t i = 0; i < vec.size(); i++)
        {
            //判断当前是否为侦听套接字
            if(vec[i]==listen_sock)
            {
                //侦听套接字
                struct sockaddr_in cli_addr;
                socklen_t cli_addrlen = sizeof(cli_addr);
                int newsockfd = accept(listen_sock,(struct sockaddr*)&cli_addr,&cli_addrlen);
                if(newsockfd < 0)
                {
                    perror("accept");
                    return 0;
                }
                printf("accept new connet from client %s : %d\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port));
                //把新连接套接字监视起来
                select_svr.Addfd(newsockfd);
            }
            else 
            {
                //新连接套接字
                //接收
                char buf[1024] = {0};
                ssize_t recv_size = recv(vec[i],buf,sizeof(buf)-1,0);
                if(recv_size < 0)
                {
                    perror("recv_size");
                    continue;
                }
                else if(recv_size == 0) 
                {
                    printf("peer close connect\n");
                    close(vec[i]);
                    select_svr.Delete(vec[i]);
                    continue;
                }
                printf("%s",buf);
                strcpy(buf,"i am server");
                send(vec[i],buf,sizeof(buf)-1,0);
            }
        }
    }
    close(listen_sock);
    return 0;

}
